package com.newtouch.bxzs.business.train.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.bxzs.business.enclosure.service.AttachmentService;
import com.newtouch.bxzs.business.train.mapper.ExaminationMapper;
import com.newtouch.bxzs.business.train.mapper.ExaminationUserMapMapper;
import com.newtouch.bxzs.business.train.model.bo.AppExaminationListBO;
import com.newtouch.bxzs.business.train.model.bo.ExaminationDetailBO;
import com.newtouch.bxzs.business.train.model.bo.ExaminationPCListBO;
import com.newtouch.bxzs.business.train.model.bo.ExaminationUserBO;
import com.newtouch.bxzs.business.train.model.vo.*;
import com.newtouch.bxzs.business.train.service.ExaminationService;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.em.AttachmentEnum;
import com.newtouch.bxzs.common.base.em.BusinessEnum;
import com.newtouch.bxzs.common.base.em.EnableEnum;
import com.newtouch.bxzs.common.base.model.Examination;
import com.newtouch.bxzs.common.base.model.ExaminationUserMap;
import com.newtouch.bxzs.common.base.model.bo.PageParam;
import com.newtouch.bxzs.common.base.model.vo.EnclosureVO;
import com.newtouch.bxzs.common.base.util.EntityToBeanUtils;
import com.newtouch.bxzs.common.base.util.UserDetailUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * 考试相关业务逻辑
 *
 * <p>
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/1/21</td>
 * <td>lanwei</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author lanwei
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class ExaminationServiceImpl implements ExaminationService {
    @Autowired
    private ExaminationMapper examinationMapper;
    @Autowired
    private ExaminationUserMapMapper examinationUserMapMapper;
    @Autowired
    private AttachmentService attachmentService;

    /**
     * 静态变量：系统日志
     */
    private static final Log logger = LogFactory.getLog(ExaminationServiceImpl.class);


    /**
     * 查询PC考试列表
     *
     * @param examinationPCListVO
     * @return
     */
    @Override
    public IPage<ExaminationPCListBO> getExaminationList(ExaminationPCListVO examinationPCListVO) {
        /*校验*/
        if (checkListPageParam(examinationPCListVO)) {
            logger.info("查询列表失败");
            throw new BaseException("-1", "传入数据有误");
        }
        /*实例化一个QueryWrapper*/
        QueryWrapper<Examination> query = new QueryWrapper<>();
        /* 考试名称 */
        if(!StringUtils.isEmpty(examinationPCListVO.getExaminationName())){
            query.like("EXAMINATION_NAME", examinationPCListVO.getExaminationName());
        }
        /* 以题目创建时间降序排列 */
        query.orderByDesc("CREATE_TIME");
        Page<Examination> p = new Page<>(examinationPCListVO.getCurrentPage(), examinationPCListVO.getPageSize());
        IPage<Examination> examinationPage = examinationMapper.selectPage(p, query);
        if (examinationPage == null) {
            return null;
        }
        IPage<ExaminationPCListBO> page = new Page<>();
        /*将转换的BO放到advertisementBOList的Records*/
        page.setRecords(EntityToBeanUtils.copyBean(examinationPage.getRecords(), ExaminationPCListBO.class));
        page.setCurrent(examinationPage.getCurrent());
        page.setPages(examinationPage.getPages());
        page.setSize(examinationPage.getSize());
        page.setTotal(examinationPage.getTotal());
        return page;
    }

    /**
     * 创建、修改考试基本信息
     *
     * @param examinationBaseInfoVO
     * @return
     */
    @Override
    public String modifyExaminationBaseInfo(ModifyExaminationBaseInfoVO examinationBaseInfoVO) {
    	
    	System.out.println("+++++++++++++++++++++++++++++");
    	
        /*判断传入数据是否合格*/
        if (examinationBaseInfoVO == null) {
            logger.info("新增或修改失败");
            throw new BaseException("-1", "传入数据有误");
        }
        
        /* 校验必传参数*/
        if(StringUtils.isEmpty(examinationBaseInfoVO.getExaminationName()) || null==examinationBaseInfoVO.getExaminationDuration()
            || StringUtils.isEmpty(examinationBaseInfoVO.getExaminationType()) || null==examinationBaseInfoVO.getExaminationStartTime()
                || null==examinationBaseInfoVO.getExaminationEndTime()){
            logger.info("新增或修改失败");
            throw new BaseException("-1", "有必填项未填！");
        }
        Examination examination=new Examination();
        /* 使用工具直接进行实体与BO的复制转换，注意字段名及类型需保持一致 */
        BeanUtil.copyProperties(examinationBaseInfoVO, examination);

        if (BeanUtil.isEmpty(examinationBaseInfoVO.getExaminationId())) {
            /*新增考试*/
            logger.info("新增考试");
            examination.setIsEnable(EnableEnum.UNENABLE_STATUS.getCode());
            examination.setExaminationPaperId(examinationBaseInfoVO.getExaminationPaperId());
            examination.setCreateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
            examination.setCreateTime(new Date());
            examination.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail().getUserId()));
            examination.setUpdateTime(new Date());
            examination.setIsDelete(false);
            examinationMapper.insert(examination);
            //更新考试人员映射信息
            updateExaminationUserMap(examination.getExaminationId(), examinationBaseInfoVO.getExaminationUserIds());
        } else {
            /*修改*/
            logger.info("修改考试");
            examination.setExaminationPaperId(examinationBaseInfoVO.getExaminationPaperId());
            examination.setUpdateUserId(Objects.requireNonNull(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId()));
            examination.setUpdateTime(new Date());
            examinationMapper.updateById(examination);
          //更新考试人员映射信息
            updateExaminationUserMap(examination.getExaminationId(), examinationBaseInfoVO.getExaminationUserIds());
        }
        return examination.getExaminationId();
    }

//    /**
//     * 设置、修改考试试卷
//     *
//     * @param examinationPaperVO
//     * @return
//     */
//    @Override
//    public String modifyExaminationPaper(ModifyExaminationPaperVO examinationPaperVO) {
//        /*判断传入数据是否合格*/
//        if (examinationPaperVO == null) {
//            logger.info("设置或修改失败");
//            throw new BaseException("-1", "传入数据有误");
//        }
//        /* 校验必传参数*/
//        if(StringUtils.isEmpty(examinationPaperVO.getExaminationId())
//                || StringUtils.isEmpty(examinationPaperVO.getExaminationPaperId())){
//            logger.info("设置或修改失败");
//            throw new BaseException("-1", "有必填项未填！");
//        }
//        Examination examination = examinationMapper.selectById(examinationPaperVO.getExaminationId());
//        if(BeanUtil.isEmpty(examination)){
//            logger.info("id不正确");
//            throw new BaseException("-1", "id不正确");
//        }
//        /*设置或修改试卷*/
//        logger.info("设置或修改试卷");
//        /*设置修改人id*/
//        examination.setUpdateUserId(Objects.requireNonNull(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId()));
//        /*设置修改时间*/
//        examination.setUpdateTime(new Date());
//        examination.setExaminationPaperId(examinationPaperVO.getExaminationPaperId());
//        examinationMapper.updateById(examination);
//        return examination.getExaminationId();
//    }

    /**
     * 设置、修改考试参考人员
     *
     * @param examinationUserMapVO
     * @return
     */
//    @Override
//    public String modifyExaminationUserMap(ModifyExaminationUserMapVO examinationUserMapVO) {
//        /*判断传入数据是否合格*/
//        if (examinationUserMapVO == null) {
//            logger.info("设置或修改失败");
//            throw new BaseException("-1", "传入数据有误");
//        }
//        /* 校验必传参数*/
//        if(StringUtils.isEmpty(examinationUserMapVO.getExaminationId())
//                || null==examinationUserMapVO.getUserIdList()){
//            logger.info("设置或修改失败");
//            throw new BaseException("-1", "有必填项未填！");
//        }
//        List<String> newUserIdList=examinationUserMapVO.getUserIdList();
//        List<String> userIdList=null;
//        /*
//        * 1、根据考试id查询数据库，看之前是否设置过考试人员，如果没有设置，直接新增
//        * 2、如果之前设置过，对比新传入的和之前的，之前有的不变，没有的新增，之前多余的删除
//        */
//        List<Map<String, Object>> examinationUserIdListInDb = examinationUserMapMapper.getExaminationUserIdListByExaminationId(examinationUserMapVO.getExaminationId());
//        if(examinationUserIdListInDb.size()==0){
//            /* 直接新增*/
//            userIdList=newUserIdList;
//        }else{
//            Set<String> newUserIdSet=new HashSet<>(newUserIdList);
//            List<String> deleteUserIdList=new ArrayList<>();
//            for(Map<String, Object> map:examinationUserIdListInDb){
//                String userId=map.get("userId").toString();
//                if(!newUserIdSet.contains(userId)){
//                    /* 之前存在，但新的记录中没有，删除*/
//                    deleteUserIdList.add(map.get("examinationUserMapId").toString());
//                }else{
//                    /* 之前存在，新的记录中也有，不再新增*/
//                    newUserIdSet.remove(userId);
//                }
//            }
//            userIdList=new ArrayList<>(newUserIdSet);
//            /* 移除多余的 */
//            if(deleteUserIdList.size()>0){
//                examinationUserMapMapper.deleteBatchIds(deleteUserIdList);
//            }
//
//        }
//        /* 新增考试人员 */
//        for(String userId:userIdList){
//            ExaminationUserMap examinationUserMap=new ExaminationUserMap();
//            examinationUserMap.setCreateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
//            examinationUserMap.setCreateTime(new Date());
//            examinationUserMap.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail().getUserId()));
//            examinationUserMap.setUpdateTime(new Date());
//            examinationUserMap.setExaminationId(examinationUserMapVO.getExaminationId());
//            examinationUserMap.setUserId(userId);
//            examinationUserMap.setIsDelete(false);
//            examinationUserMapMapper.insert(examinationUserMap);
//        }
//        return examinationUserMapVO.getExaminationId();
//    }

    /**
     * 撤销、发布考试
     *
     * @param examinationEnableStateVO
     */
    @Override
    public void changeExaminationEnableState(ChangeExaminationEnableStateVO examinationEnableStateVO) {
        /*校验*/
        if (examinationEnableStateVO == null || StringUtils.isEmpty(examinationEnableStateVO.getExaminationId())
             || (!Objects.equals(examinationEnableStateVO.getIsEnable(),EnableEnum.UNENABLE_STATUS.getCode())
                && !Objects.equals(examinationEnableStateVO.getIsEnable(),EnableEnum.ENABLE_STATUS.getCode()))) {
            logger.info("修改状态失败");
            throw new BaseException("-1", "传入数据有误");
        }
        Examination examination = examinationMapper.selectById(examinationEnableStateVO.getExaminationId());
        if(BeanUtil.isEmpty(examination)){
            logger.info("id不正确");
            throw new BaseException("-1", "id不正确");
        }
        if(Objects.equals(examinationEnableStateVO.getIsEnable(),EnableEnum.UNENABLE_STATUS.getCode())
                && examinationEnableStateVO.getIsEnable().equals(examination.getIsEnable())){
            logger.info("修改状态失败");
            throw new BaseException("-1", "传入的考试已经处于未发布状态");
        }else if(Objects.equals(examinationEnableStateVO.getIsEnable(),EnableEnum.ENABLE_STATUS.getCode())
                && examinationEnableStateVO.getIsEnable().equals(examination.getIsEnable())){
            logger.info("修改状态失败");
            throw new BaseException("-1", "传入的考试已经处于已发布状态");
        }
        /* 设置启用状态*/
        examination.setIsEnable(examinationEnableStateVO.getIsEnable());
        /*设置修改时间和修改人*/
        examination.setUpdateTime(new Date());
        examination.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
        examinationMapper.updateById(examination);
    }

    /**
     * 删除考试
     *
     * @param examinationIds 考试id集合
     */
    @Override
    public Integer deleteExamination(List<String> examinationIds) {
        /*校验*/
        if (CollectionUtil.isEmpty(examinationIds)) {
            logger.info("删除失败");
            throw new BaseException("-1", "集合为空");
        }
        QueryWrapper<Examination> query=new QueryWrapper<>();
        query.in("EXAMINATION_ID", examinationIds).eq("IS_ENABLE", EnableEnum.ENABLE_STATUS.getCode());
        List<Examination> examinationList = examinationMapper.selectList(query);
        /*判断集合内是否有发布状态的考试*/
        if (!CollectionUtil.isEmpty(examinationList)) {
            logger.info("删除失败");
            throw new BaseException("-1", "存在状态为已发布的考试");
        }
        /*批量逻辑删除产品*/
        return examinationMapper.deleteBatchIds(examinationIds);
    }

    /**
     * 获取考试详情
     *
     * @param examinationId 考试id
     * @return
     */
    @Override
    public ExaminationDetailBO getExaminationDetail(String examinationId) {
        /*校验*/
        if (StringUtils.isEmpty(examinationId)) {
            logger.info("查看详情失败");
            throw new BaseException("-1", "id为空");
        }
        Examination examination = examinationMapper.selectById(examinationId);
        if (examination == null) {
            return null;
        }
        ExaminationDetailBO examinationDetailBO = new ExaminationDetailBO();
        /* 使用工具直接进行实体与BO的复制转换，注意字段名及类型需保持一致 */
        BeanUtil.copyProperties(examination, examinationDetailBO);
        HashMap<String, List<String>> result = attachmentService.getEnclosureList(new EnclosureVO(examinationId, null));
        if (result != null) {
            // 获取缩略图地址
            List<String> list = result.get(String.valueOf(AttachmentEnum.THUMBNAIL_PICTURE.getCode()));
            if (list != null) {
                for (String url : list) {
                    examinationDetailBO.setAttachmentUrl(url);
                }
            }
        }
        return examinationDetailBO;
    }

    /**
     * 获取考试设置里面的所有用户列表
     *
     * @param examinationUserForExaminationListVO
     * @return
     */
    @Override
    public IPage<ExaminationUserBO> getExaminationUserForExamination(ExaminationUserForExaminationListVO examinationUserForExaminationListVO) {
        /*校验*/
        if (checkListPageParam(examinationUserForExaminationListVO)) {
            logger.info("查询列表失败");
            throw new BaseException("-1", "传入数据有误");
        }
        String examinationId=examinationUserForExaminationListVO.getExaminationId();
        Page<ExaminationUserBO> page = new Page<ExaminationUserBO>(examinationUserForExaminationListVO.getCurrentPage(),examinationUserForExaminationListVO.getPageSize());
        return examinationUserMapMapper.getExaminationUserList(examinationId,page);
    }


    /**
     * 校验分页参数
     * @param pageParam
     * @return
     */
    private boolean checkListPageParam(PageParam pageParam){
        if (pageParam == null || pageParam.getPageSize() == null || pageParam.getCurrentPage() == null ||
                StringUtils.isEmpty(pageParam.getPageSize()) || StringUtils.isEmpty(pageParam.getCurrentPage())
            || pageParam.getCurrentPage()<1) {
           return true;
        }
        return false;
    }

    
    /* 
     * 更新考试人员映射信息
     */
    @Override
    public void updateExaminationUserMap(String examinationId, List<String> examinationUserIds) {
        if (examinationUserIds != null && examinationUserIds.size() > 0) {
            QueryWrapper<ExaminationUserMap> query = new QueryWrapper<ExaminationUserMap>();
            query.eq("EXAMINATION_ID", examinationId);
            int affectRows = examinationUserMapMapper.delete(query);
            logger.info("删除成功" + affectRows);
            /*新建考试用户映射信息*/
            for (String examinationUserId : examinationUserIds) {
                ExaminationUserMap examinationUserMap = new ExaminationUserMap();

                examinationUserMap.setExaminationId(examinationId);
                examinationUserMap.setUserId(examinationUserId);
                examinationUserMap.setCreateTime(new Date());
                examinationUserMap.setCreateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail().getUserId()));
                examinationUserMapMapper.insert(examinationUserMap);
            }
        }
    }

    /* 
     * app获取考试列表
     */
    @Override
    public IPage<AppExaminationListBO> getAppExaminationList(AppExaminationListVO appExaminationListVO) {
        Page<AppExaminationListBO> page = new Page<AppExaminationListBO>(appExaminationListVO.getCurrentPage(),appExaminationListVO.getPageSize());
        return examinationMapper.getAppExaminationList(appExaminationListVO.getExaminationType().equals(BusinessEnum.SIMULATE.getCode())?BusinessEnum.SIMULATE.getName():BusinessEnum.OFFICIAL.getName(),page);
    }
}
